using System;
using System.IO;
using System.Reflection;
using System.Data;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Resources;

namespace ipi.MCC.Global
{
    public class Functions
    {        
        public Functions() { }

        public static string TreePosition_InternalColumnName
        {
            get
            {
                Assembly asMCCGlobal = Assembly.Load("MCC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c1bcda0f03a0d11e");

                ResourceManager resMgr = new ResourceManager("ipi.MCC._12.Resources.MCCResources", asMCCGlobal);
                string sName = resMgr.GetString("TreePosition_InternalColumnName");
                resMgr = null;
                asMCCGlobal = null;

                return sName;
                //return MCC.Global.MCCResources.TreePosition_InternalColumnName;
            }
        }

        public static string TreeList_Title
        {
            get
            {
                Assembly asMCCGlobal = Assembly.Load("MCC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c1bcda0f03a0d11e");

                ResourceManager resMgr = new ResourceManager("ipi.MCC._12.Resources.MCCResources", asMCCGlobal);
                string sName = resMgr.GetString("TreeList_Title");
                resMgr = null;
                asMCCGlobal = null;

                return sName;
              //  return MCC.Global.MCCResources.TreeList_Title;
            }
        }

        internal static void WriteEventLog(string ClassName, string ExceptionName, string ErrorNumber, string ErrorText)
        {
            string sFullExceptionMessage = ClassName.PadRight(100, ' ') + ExceptionName.PadRight(25, ' ') + ErrorNumber.PadRight(15, ' ') + ErrorText;

            try
            {
                Debug.WriteLine(sFullExceptionMessage);
                Console.WriteLine(sFullExceptionMessage);

                try
                {
                    if (!EventLog.SourceExists(ipi.MCC.Global.Resources.Resources.EventLogSource))
                    {
                        EventLog.CreateEventSource(new EventSourceCreationData(ipi.MCC.Global.Resources.Resources.EventLogSource, ipi.MCC.Global.Resources.Resources.EventLogName));
                    }

                    EventLog eventlog = new EventLog();
                    eventlog.Log = ipi.MCC.Global.Resources.Resources.EventLogName;
                    eventlog.MachineName = ".";
                    eventlog.Source = ipi.MCC.Global.Resources.Resources.EventLogSource;
                    eventlog.WriteEntry(sFullExceptionMessage, EventLogEntryType.Error);
                }
                catch (Exception)
                { }

                WriteLogFile(sFullExceptionMessage);
            }
            catch (Exception exc)
            {
                Debug.WriteLine(Exceptions.GetMethodPath(MethodBase.GetCurrentMethod().ReflectedType, MethodBase.GetCurrentMethod()) + ": " + exc.Message +
                                                    "; " + sFullExceptionMessage);
            }
        }

        public static void WriteEventLog(Type CurrentType, MethodBase Method, string message, LoggingType ltCurrent)
        {
            string sClassName = Exceptions.GetMethodPath(CurrentType, Method);
            try
            {
                Debug.WriteLine(sClassName + ": " + message);
                Console.WriteLine(sClassName + ": " + message);
                string sLogText = string.Empty;
                if ((ltCurrent == LoggingType.Exception) || (ltCurrent == LoggingType.Global_Exception))
                {
                    try
                    {
                        if (!EventLog.SourceExists(ipi.MCC.Global.Resources.Resources.EventLogSource))
                        {
                            EventLog.CreateEventSource(new EventSourceCreationData(ipi.MCC.Global.Resources.Resources.EventLogSource, ipi.MCC.Global.Resources.Resources.EventLogName));
                        }

                        EventLog eventlog = new EventLog();
                        eventlog.Log = ipi.MCC.Global.Resources.Resources.EventLogName;
                        eventlog.MachineName = ".";
                        eventlog.Source = ipi.MCC.Global.Resources.Resources.EventLogSource;
                        eventlog.WriteEntry(sClassName + ": " + message.ToString(), EventLogEntryType.Error);
                    }
                    catch (Exception)
                    { }
                }
                else
                {
                    sLogText = message;
                }

                WriteLogFile(sLogText);
            }
            catch (Exception exc)
            {
                Debug.WriteLine(Exceptions.GetMethodPath(MethodBase.GetCurrentMethod().ReflectedType, MethodBase.GetCurrentMethod()) + ": " + exc.Message +
                                                    "; Classname: " + sClassName +
                                                    "; Message: " + message);
            }
        }

        private static void WriteLogFile(string sLogText)
        {
            DateTime dtLog = DateTime.Now;

            SPSecurity.RunWithElevatedPrivileges(
            delegate()
            {
                string sLogFile = SPDiagnosticsService.Local.LogLocation + Path.DirectorySeparatorChar + Constants.LogFile_Name + "_" + dtLog.ToString("yyyyMMdd") + ".log";

                FileStream fLog = new FileStream(sLogFile, FileMode.Append, FileAccess.Write);
                StreamWriter sLog = new StreamWriter(fLog);

                try
                {
                    sLog.BaseStream.Seek(0, SeekOrigin.End);
                    sLog.WriteLine(dtLog.ToString("yyyy-MM-dd HH:mm:ss") + ": " + sLogText);
                }
                finally
                {
                    sLog.Flush();
                    sLog.Close();
                    fLog.Close();
                }
            });
        }

        public static SPList GetTreeList(SPWeb spwRoot)
        {
            SPList splReturn = null;

            try
            {
                bool bCatchAccessDeniedException = SPSecurity.CatchAccessDeniedException;
                try
                {
                    SPSecurity.CatchAccessDeniedException = false;
                    foreach (SPList splCurrent in spwRoot.Lists)
                    {
                        if (splCurrent.Title == Functions.TreeList_Title)
                        {
                            splReturn = splCurrent;
                        }
                    }
                }
                finally
                {
                    SPSecurity.CatchAccessDeniedException = bCatchAccessDeniedException;
                }
            }
            catch (UnauthorizedAccessException)
            {
                throw(new TreeListAccessDeniedException());
            }
            catch (Exception exc)
            {
                Exceptions.HandleException(exc, MethodBase.GetCurrentMethod().ReflectedType, MethodBase.GetCurrentMethod(), LoggingType.Exception);
            }

            if (splReturn == null)
            {
                throw (new TreeListAccessDeniedException());
            }

            return splReturn;
        }

        #region TreeNode
        public static SPListItem GetSingleTreeNode(SPList splTree, int iNodeID)
        {
            SPListItem liResult = null;
            SPListItemCollection licNodes = GetTreeNode(splTree, iNodeID);
            if (licNodes.Count > 0)
            {
                liResult = licNodes[0];
            }

            return liResult;
        }

        public static SPListItemCollection GetTreeNode(SPList splTree, int iNodeID)
        {
            return GetTreeNode(splTree, "<Where><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">" + iNodeID.ToString() + "</Value></Eq></Where>");
        }
        
        public static SPListItemCollection GetTreeChildNode(SPList splTree, int iNodeID)
        {
            string sCAMLGetNode = "";
            if (iNodeID == -1)
            {
                sCAMLGetNode = "<Where><IsNull><FieldRef Name=\"ParentNode\" /></IsNull></Where>";
            }
            else
            {
                sCAMLGetNode = "<Where><Eq><FieldRef Name=\"ParentNode\" /><Value Type=\"Lookup\">" + iNodeID.ToString() + "</Value></Eq></Where>";
            }

            WebSettings wsRoot = new WebSettings(splTree.ParentWeb.Site);
            if (!wsRoot.UseAlphanummericSort)
            {
                sCAMLGetNode += "<OrderBy><FieldRef Name=\"NodeOrder\" /></OrderBy>";
            }
            else
            {
                sCAMLGetNode += "<OrderBy><FieldRef Name=\"Title\" /></OrderBy>";
            }

            return GetTreeNode(splTree, sCAMLGetNode);
        }

        private static SPListItemCollection GetTreeNode(SPList splNodeList, string sCAML)
        {
            SPListItemCollection licCurrent = null;

            try
            {
                if (splNodeList != null)
                {
                    SPQuery spQuery = new SPQuery();
                    spQuery.ViewFields = "<FieldRef Name='ID'/><FieldRef Name='Title'/><FieldRef Name='ParentNode'/><FieldRef Name='NodeOrder'/>";
                    spQuery.Query = sCAML;
                    licCurrent = splNodeList.GetItems(spQuery);
                }

            }
            catch (Exception exc)
            {
                Exceptions.HandleException(exc, MethodBase.GetCurrentMethod().ReflectedType, MethodBase.GetCurrentMethod(), LoggingType.Exception);
            }

            return licCurrent;
        }

        public static int GetNodeIDbyTreeName(SPList splNodeList, string treename)
        {
            SPQuery spQuery = new SPQuery();
            spQuery.ViewFields = "<FieldRef Name='ID'/>";
            spQuery.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + treename + "</Value></Eq></Where>";

            spQuery.Folder = splNodeList.RootFolder;

            SPListItemCollection itemColl = splNodeList.GetItems(spQuery);

            if (itemColl.Count > 0)
            {
                return itemColl[0].ID;
            }
            return -1;
        }
        
        /// <summary>
        /// Function for Getting the NodeID from a QueryString with Form Folder/SubFolder/SubSubFolder...
        /// </summary>
        /// <param name="querystring">The Requets.QueryString Parameter 'Path' of the Page</param>
        /// <returns></returns>
        public static int GetNodeIdForExpand(SPList splNodes, string querystring, string separator)
        {
            //Split the QueryString
            string[] nodes = querystring.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);

            int idNode = -1;

            //QueryString contains only one Element, Folder is unique
            if (nodes.Length == 1)
            {
                idNode = Functions.GetNodeIDbyTreeName(splNodes, nodes[nodes.Length - 1]);
            }
            //QueryString contains more than one Element, Folder is not unique. QueryString is a part of a FolderPath
            else
            {
                bool bfoundNodes = false;

                //Get the ID of the first Element of the QueryString
                idNode = Functions.GetNodeIDbyTreeName(splNodes, nodes[0]);

                if (idNode != -1)
                {
                    int index = 0;
                    foreach (string node in nodes)
                    {
                        if (index != 0)
                        {
                            //Load ChildNodes from the parent Element of the QueryString
                            SPListItemCollection items = Functions.GetTreeChildNode(splNodes, idNode);

                            //Search the ID of the current Element 
                            foreach (SPListItem item in items)
                            {
                                if (item.Title == node)
                                {
                                    bfoundNodes = true;
                                    idNode = item.ID;
                                }
                            }

                            //if element not found
                            if (!bfoundNodes)
                            {
                                idNode = -1;
                                break;
                            }
                        }

                        index++;
                    }
                }
            }

            return idNode;
        }

        #endregion
    }
}
